<template>
  <div class="graph flex-column">
    <div class="graph-body">
      <div class="graph-container abs" :style="flowViewStyle" ref="flowTree">
        <svg class="graph-svg">
          <defs>
            <marker id="pathStart" markerWidth="10" markerHeight="10" orient="auto" viewBox="-5 -5 10 10">
              <circle r="4" class="marker-start" />
            </marker>
            <marker id="pathMid" markerWidth="10" markerHeight="10" orient="auto" viewBox="-5 -5 10 10">
              <path d="M4,0 l-8,-3 l1.5,3 l-1.5,3,z " class="marker-mid" />
            </marker>
            <marker id="pathEnd" markerWidth="8" markerHeight="8" orient="auto" refX="-2.5" viewBox="-5 -5 10 10">
              <!-- <circle r="3" class="marker-start" /> -->
              <!-- <path d="M0 -3,l-3 3,l3 3,z" class="marker-end"  /> -->
              <path d="M4,0 l-8,-3 l1.5,3 l-1.5,3,z " class="marker-end" />
            </marker>
            <marker id="marker-arrow" markerWidth="8" markerHeight="8" orient="auto" refX="4" viewBox="-5 -5 10 10">
              <!-- <circle r="3" class="marker-start" /> -->
              <!-- <path d="M0 -3,l-3 3,l3 3,z" class="marker-end"  /> -->
              <path d="M4,0 l-8,-3 l1.5,3 l-1.5,3,z " class="marker-end" />
            </marker>
          </defs>

          <!-- <g class="graph-line">
        <path class="line-arrow-end" :d="item.arrowEnd" />
          </g>-->
          <!-- <rect
            class="graph-node"
            rx="2"
            ry="2"
            :x="item.x"
            :y="item.y"
            :width="item.width"
            :height="item.height"
            v-for="item in graph.nodes"
            :key="item.id"
          /> -->

          <g class="line-g" v-for="(item, i) in graph.lines" :key="'line' + i" :rel="i" :style="item.lineStroke">
            <marker :id="'lineStart' + i" markerWidth="10" markerHeight="10" orient="auto" viewBox="-5 -5 10 10">
              <circle r="4" class="marker-start" />
            </marker>
            <marker :id="'lineEnd' + i" markerWidth="7" markerHeight="7" orient="auto" refX="4" refY="8" viewBox="0 0 16 16">
              <path d="M2,3 l12,5  l-12,5 l2,-5 z " class="marker-end" />
            </marker>
            <path class="graph-line" :style="`marker-start:url(#${'lineStart' + i});marker-end:url(#${'lineEnd' + i});`" :d="item.d" />
            <slot name="line" v-bind="{ line: item, key: i }"></slot>
          </g>
        </svg>

        <div class="graph-node" v-for="(item, i) in graph.nodes" :key="item.id" :class="nodeClass" :style="flowStyle(item)">
          <slot name="node" v-bind="{ node: item, data: item.data, key: i }"></slot>
          <i class="node-shift" />
        </div>
      </div>
    </div>
    <div class="graph-head graph-contorl">
      <!-- <slot name="headAdd"></slot> -->
      <span>
        <!-- <i class="btn click el-icon-circle-plus" title="放大" @click="flowViewScale(0.2)"></i> -->
        <!-- <i class="btn click el-icon-full-screen" title="还原" @click="config.scale=1"></i> -->
        <!-- <i class="btn click el-icon-remove" @click="flowViewScale(-0.2)" title="缩小"></i> -->

        <!-- <span slot="reference" class="btn click el-icon-s-tools" title="视图设置">aa</span> -->
        <!-- <div>
          <el-checkbox v-model="graphConfig.center">居中</el-checkbox>
          <div>
            <el-radio-group v-model="graphConfig.direction">
              <el-radio label="horizontal">水平</el-radio>
              <el-radio label="vertical">垂直</el-radio>
            </el-radio-group>
          </div>
          <div>
            <el-radio-group v-model="graphConfig.lineType">
              <el-radio label="curve">曲线</el-radio>
              <el-radio label="straight">直线</el-radio>
            </el-radio-group>
          </div>
        </div> -->
        <!-- <el-popover placement="bottom" trigger="click" :offset="5"> </el-popover> -->
      </span>
    </div>
  </div>
</template>
<script>
import Graph from "./Graph.js";
export default {
  props: {
    data: {},
    nodeClass: {},
    active: {},
    mini: {},
    config: { default: null },
    lines: {}
  },
  components: {},
  data() {
    return {
      scale: 1,
      graph: new Graph()
    };
  },
  computed: {
    graphConfig() {
      return {
        nodeWidth: 200,
        nodeHeight: 90,
        marginX: 80,
        marginY: 20,
        xRoot: 15,
        yRoot: 15,
        direction: "horizontal", //布局方式:(垂直布局:vertical;水平布局:horizontal)
        center: true, //节点是否居中
        // lineType: "curve" //节点连线风格:(直线:straight;曲线:curve )
        ...this.config
      };
    },
    flowViewStyle() {
      let scale = this.scale || 1;
      let sx = scale;
      let sy = scale;
      return `transform: scale(${sx},${sy});`;
    }
  },
  watch: {
    // active(fresh, old) {
    //   // this.setFlow();
    // },
    data: {
      handler(fresh, old) {
        this.setGraph();
      },
      immediate: true
    },
    "graphConfig.yRoot": {
      handler(fresh, old) {
        this.setGraph();
      }
    }
    // config: {
    //   handler(fresh, old) {
    //     console.log("config", fresh);
    //     this.setGraph();
    //   }
    //   // deep: true
    // },
    // "config.center"(fresh, old) {
    //   this.setGraph();
    // },
    // "config.direction"(fresh, old) {
    //   if (fresh == "horizontal") {
    //     this.config.marginX = 80;
    //     this.config.marginY = 20;
    //   } else {
    //     this.config.marginX = 20;
    //     this.config.marginY = 80;
    //   }
    //   this.setGraph();
    // },
    // "config.lineType"(fresh, old) {
    //   this.setGraph();
    // }
  },

  methods: {
    flowViewScale(val) {
      let scale = this.scale + val;
      this.scale = Math.max(Math.min(scale, 1), 0.2);
    },
    setGraph() {
      let data = this.data;
      this.graph.layoutOfTree(data, this.graphConfig);
    },
    flowStyle(item) {
      let node = item;
      let width = node.width;
      let height = node.height;
      let x = node.x;
      let y = node.y;
      return `width:${width}px;height:${height}px;left:${x}px;top:${y}px;`;
    }
  },
  beforeDestroy() {
    this.graph.clear();
  }
};
</script>
<style>
.graph {
  overflow: auto;
  /* padding: 5px; */
}
.graph-head {
  overflow: auto;
}
.graph-contorl {
  position: absolute;
  /* right: 0px; */
  left: 0;
  bottom: 11px;
  z-index: 10;
  padding: 2px 10px;
  /* background: #0001; */
  /* text-align: right; */
  /* border-top: 1px solid #ddd7; */
  /* border-bottom:1px solid #ddd9 ; */
}
.graph-contorl .btn {
  padding: 3px;
  margin: 0 3px;
  /* color: #eee; */
  /* font-size: 16px; */
}
.graph-body {
  flex-grow: 1;
  position: relative;
  overflow: auto;
  /* display: flex;
  align-items: center; */
}
.graph-container {
  transition: 0.3s;
  transform-origin: 0 0;
  overflow: visible;
  /* position: absolute;
  position: relative;
  min-height: 1px;
  
  width: 100%; */
}
.graph-svg {
  position: absolute;
  z-index: 1;
  height: 100%;
  width: 100%;
  fill: transparent;

  /* background: linear-gradient(to left, #f00 0, #fff 100%); */
  --stroke: #ddd9;
  --stroke-line: #aaa;
  stroke: var(--stroke);
  overflow: visible !important;
  /* background: linear-gradient(to left, #f00 0, #fff 100%); */
}
text {
  fill: var(--stroke-line);
}
.node-shift {
  position: absolute;
  bottom: 0px;
  right: 0px;
  width: 1px;
  height: 1px;
  transform: translate(15px, 15px);
}
.graph-node {
  position: absolute;
  z-index: 10;
  stroke-width: 0.8;
  transition: 0.5s;
  stroke: #ddda;
  /* background-color: #67c23a;
  inset: (10% 20% round 5px); */
  /* stroke-dasharray: 12 5 5;
  animation: dashoffset 40s infinite linear; */
}
.graph-line {
  position: absolute;
  z-index: 10;
  stroke-width: 1.2;
  transition: 0.3s;
  stroke: var(--stroke-line);
}

@keyframes stroke {
  0% {
    stroke: #f1be5d;
  }
  30% {
    stroke: #67c23a;
  }
  70% {
    stroke: #379ee2;
  }
  100% {
    stroke: #f1be5d;
  }
}

@keyframes fill {
  0% {
    stroke: #f1be5d99;
  }
  30% {
    stroke: #67c23a;
  }
  70% {
    stroke: #379ee2;
  }
  100% {
    stroke: #f1be5d99;
  }
}
@keyframes dashoffset {
  0% {
    stroke-dashoffset: 0%;
  }
  100% {
    stroke-dashoffset: -100%;
  }
}

.marker-start {
  fill: #bbbb;
  fill: var(--stroke-line);
  stroke: transparent;
  transform: scale(0.5);
}
.marker-mid {
  fill: rgba(182, 204, 219, 0.6);
  stroke: transparent;
  transform: scale(0.8, 0.6);
}
.marker-end {
  stroke: var(--stroke-line);
  fill: var(--stroke-line);
}
.graph-anim .graph-node {
  /* stroke-dasharray: 12 5 5; */
  /* stroke-width: .5;
  animation: dashoffset 40s infinite linear, stroke 5s infinite; */
}
.graph-anim .marker-start,
.graph-anim .marker-end {
  animation: fill 5s infinite, stroke 5s infinite;
  /* transform: scale(1.3); */
}
.graph-anim .graph-line {
  /* stroke-width: 1; */
  stroke-dasharray: 0.3% 0.3% 0.6% 0.3%;
  animation: dashoffset 40s infinite linear, stroke 5s infinite;
}
</style>
